#pragma once

#include "muduo/net/TcpConnection.h"
#include "muduo/proto/codec.h"
#include "muduo/proto/dispatcher.h"
#include "../common/Log.hpp"
#include "../common/UUIDHelper.hpp"
#include "../common/message.pb.h"
#include "../common/protocol.pb.h"
#include "Consumer.hpp"
#include "Channel.hpp"
#include <string>
#include <unordered_map>
#include <memory>
#include <vector>
#include <mutex>
#include <condition_variable>
#include <functional>

namespace micromq
{
    class ChannelManager
    {
    public:
        using ptr = std::shared_ptr<ChannelManager>;
    public:
        ChannelManager()
        {}

        Channel::ptr addChannel(const muduo::net::TcpConnectionPtr& conn, const ProtobufCodecPtr& codec)
        {
            std::unique_lock<std::mutex> lock(_mtx);
            Channel::ptr channel = std::make_shared<Channel>(conn, codec);
            _channels[channel->getChannelId()] = channel;
            return channel;
        }

        void removeChannel(const std::string& channelId)
        {
            std::unique_lock<std::mutex> lock(_mtx);
            _channels.erase(channelId);
        }

        Channel::ptr getChannel(const std::string& channelId)
        {
            std::unique_lock<std::mutex> lock(_mtx);
            auto it = _channels.find(channelId);
            if(it == _channels.end()) return nullptr;
            return it->second;
        }

        ~ChannelManager()
        {}
    private:
        std::mutex _mtx;
        std::unordered_map<std::string, Channel::ptr> _channels; // <信道Id，信道指针>
    };
}